/**
 * Licensed under the Apache License Version 2.0.
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations
 * under the License.
 */
package net.interknit.knitter.cg.view;

import net.interknit.knitter.cg.layout.ArrayElement;
import net.interknit.knitter.cg.layout.LayoutElement;
import net.interknit.knitter.cg.model.JavaType;
import net.interknit.knitter.cg.util.ReflectionHelper;
import net.interknit.knitter.cg.util.Utils;

/**
 *
 */
public class ArrayTypeView extends JavaTypeView
{
	public ArrayTypeView(JavaType javaType)
	{
		super(javaType);
	}

	@Override
	protected String[] getAdditionalPlaceholders()
	{
		return new String[] {
				"STATE_COMPONENT_DECLARATION",
				"STATE_COMPONENT_NAME",
				"STATE_COMPONENT_INSTANTIATION",
				"VALUE_COMPONENT_INSTANTIATION",
				"STATE_COMPONENT_UNWRAP_CLAUSE",
				"VALUE_ADDITIONAL_ARRAY_NOTIFIERS_INIT",
		};
	}

	@Override
	public LayoutElement getLayoutElement()
	{
		return new ArrayElement(this);
	}

	@Override
	public String STATE_DECLARATION()
	{
		StringBuilder sb = new StringBuilder();

		JavaType javaType = getJavaType();

		assertCondition(javaType.getInspector().isArrayType(), "STATE_DECLARATION");

		JavaType componentJavaType = javaType.getComponentJavaType();

		sb.append(JavaTypeViewFactory.create(componentJavaType).ADAPTER_DECLARATION()).append("[]");

		return sb.toString();
	}

	@Override
	public String STATE_INSTANTIATION()
	{
		return STATE_DECLARATION().replaceAll("\\[\\]", "[0]");
	}

	@Override
	public String VALUE_INSTANTIATION()
	{
		StringBuilder sb = new StringBuilder();

		JavaType javaType = getJavaType();

		assertCondition(javaType.getInspector().isArrayType(), "VALUE_INSTANTIATION");

		sb.append(ReflectionHelper.getClassName(javaType.getTypeClass()));

		int arrayDimensions = javaType.getArrayDimensions();

		return sb.append(Utils.chain("[0]", arrayDimensions)).toString();
	}

	public String STATE_COMPONENT_NAME()
	{
		return ReflectionHelper.getStandardTypeName(STATE_COMPONENT_DECLARATION());
	}

	public String STATE_COMPONENT_DECLARATION()
	{
		return STATE_DECLARATION().replaceAll("\\[\\]", "");
	}

	public String STATE_COMPONENT_INSTANTIATION()
	{
		JavaType javaType = getJavaType();

		assertCondition(javaType.getInspector().isArrayType(), "STATE_COMPONENT_INSTANTIATION");

		JavaType componentJavaType = javaType.getComponentJavaType();

		if(componentJavaType.getInspector().isPrimitiveType())
		{
			return JavaTypeViewFactory.create(componentJavaType).ADAPTER_INSTANTIATION();
		}
		else
		{
			return STATE_DECLARATION().replaceAll("\\[\\]", "");
		}
	}

	public String VALUE_COMPONENT_INSTANTIATION()
	{
		StringBuilder sb = new StringBuilder();

		JavaType javaType = getJavaType();

		assertCondition(javaType.getInspector().isArrayType(), "VALUE_COMPONENT_INSTANTIATION");

		JavaType rawComponentJavaType = javaType.getRawComponentJavaType();

		sb.append(ReflectionHelper.getClassName(rawComponentJavaType.getTypeClass()));

		return sb.toString();
	}

	public String STATE_COMPONENT_UNWRAP_CLAUSE()
	{
		JavaType javaType = getJavaType();

		assertCondition(javaType.getInspector().isArrayType(), "STATE_COMPONENT_UNWRAP_CLAUSE");

		JavaType componentJavaType = javaType.getComponentJavaType();

		return JavaTypeViewFactory.create(componentJavaType).UNWRAP_CLAUSE();
	}

	public String VALUE_ADDITIONAL_ARRAY_NOTIFIERS_INIT()
	{
		JavaType javaType = getJavaType();

		assertCondition(javaType.getInspector().isArrayType(), "STATE_DECLARATION");

		int additionalArrayDim = javaType.getArrayDimensions() - 1;

		return Utils.chain("[0]", additionalArrayDim);
	}
}
